{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pivot Data from Long to Wide Form"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>variable</th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Alice</td>\n",
       "      <td>wk1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Alice</td>\n",
       "      <td>wk2</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Alice</td>\n",
       "      <td>wk3</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Alice</td>\n",
       "      <td>wk4</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Bob</td>\n",
       "      <td>wk1</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Bob</td>\n",
       "      <td>wk2</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Bob</td>\n",
       "      <td>wk3</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Bob</td>\n",
       "      <td>wk4</td>\n",
       "      <td>33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Carla</td>\n",
       "      <td>wk1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Carla</td>\n",
       "      <td>wk2</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>Carla</td>\n",
       "      <td>wk3</td>\n",
       "      <td>39</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Carla</td>\n",
       "      <td>wk4</td>\n",
       "      <td>40</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     name variable  value\n",
       "0   Alice      wk1      5\n",
       "1   Alice      wk2      9\n",
       "2   Alice      wk3     20\n",
       "3   Alice      wk4     22\n",
       "4     Bob      wk1      7\n",
       "5     Bob      wk2     11\n",
       "6     Bob      wk3     17\n",
       "7     Bob      wk4     33\n",
       "8   Carla      wk1      6\n",
       "9   Carla      wk2     13\n",
       "10  Carla      wk3     39\n",
       "11  Carla      wk4     40"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = [\n",
    "    {\"name\": \"Alice\", \"variable\": \"wk1\", \"value\": 5},\n",
    "    {\"name\": \"Alice\", \"variable\": \"wk2\", \"value\": 9},\n",
    "    {\"name\": \"Alice\", \"variable\": \"wk3\", \"value\": 20},\n",
    "    {\"name\": \"Alice\", \"variable\": \"wk4\", \"value\": 22},\n",
    "    {\"name\": \"Bob\", \"variable\": \"wk1\", \"value\": 7},\n",
    "    {\"name\": \"Bob\", \"variable\": \"wk2\", \"value\": 11},\n",
    "    {\"name\": \"Bob\", \"variable\": \"wk3\", \"value\": 17},\n",
    "    {\"name\": \"Bob\", \"variable\": \"wk4\", \"value\": 33},\n",
    "    {\"name\": \"Carla\", \"variable\": \"wk1\", \"value\": 6},\n",
    "    {\"name\": \"Carla\", \"variable\": \"wk2\", \"value\": 13},\n",
    "    {\"name\": \"Carla\", \"variable\": \"wk3\", \"value\": 39},\n",
    "    {\"name\": \"Carla\", \"variable\": \"wk4\", \"value\": 40},\n",
    "]\n",
    "\n",
    "\n",
    "df = pd.DataFrame(df)\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reshaping to wide form:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>wk1</th>\n",
       "      <th>wk2</th>\n",
       "      <th>wk3</th>\n",
       "      <th>wk4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Alice</td>\n",
       "      <td>5</td>\n",
       "      <td>9</td>\n",
       "      <td>20</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Bob</td>\n",
       "      <td>7</td>\n",
       "      <td>11</td>\n",
       "      <td>17</td>\n",
       "      <td>33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Carla</td>\n",
       "      <td>6</td>\n",
       "      <td>13</td>\n",
       "      <td>39</td>\n",
       "      <td>40</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    name  wk1  wk2  wk3  wk4\n",
       "0  Alice    5    9   20   22\n",
       "1    Bob    7   11   17   33\n",
       "2  Carla    6   13   39   40"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(index=\"name\", names_from=\"variable\", values_from=\"value\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pivoting on multiple columns is possible :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>n</th>\n",
       "      <th>pct</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>10.0</td>\n",
       "      <td>0.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>20.0</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>30.0</td>\n",
       "      <td>0.3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   name     n  pct\n",
       "0     1  10.0  0.1\n",
       "1     2  20.0  0.2\n",
       "2     3  30.0  0.3"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = [\n",
    "    {\"name\": 1, \"n\": 10.0, \"pct\": 0.1},\n",
    "    {\"name\": 2, \"n\": 20.0, \"pct\": 0.2},\n",
    "    {\"name\": 3, \"n\": 30.0, \"pct\": 0.3},\n",
    "]\n",
    "\n",
    "\n",
    "df = pd.DataFrame(df)\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>num</th>\n",
       "      <th>n_1</th>\n",
       "      <th>n_2</th>\n",
       "      <th>n_3</th>\n",
       "      <th>pct_1</th>\n",
       "      <th>pct_2</th>\n",
       "      <th>pct_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>20.0</td>\n",
       "      <td>30.0</td>\n",
       "      <td>0.1</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0.3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   num   n_1   n_2   n_3  pct_1  pct_2  pct_3\n",
       "0    0  10.0  20.0  30.0    0.1    0.2    0.3"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(\n",
    "    df.assign(num=0).pivot_wider(\n",
    "        index=\"num\", names_from=\"name\", values_from=[\"n\", \"pct\"], names_sep=\"_\"\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You may choose not to flatten the columns, by setting `flatten_levels` to ``False``:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>step</th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>1</td>\n",
       "      <td>20</td>\n",
       "      <td>30</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>5.5</td>\n",
       "      <td>2</td>\n",
       "      <td>25</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>6.1</td>\n",
       "      <td>1</td>\n",
       "      <td>22</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>6.1</td>\n",
       "      <td>2</td>\n",
       "      <td>18</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  step   a   b\n",
       "0  5.5     1  20  30\n",
       "1  5.5     2  25  37\n",
       "2  6.1     1  22  19\n",
       "3  6.1     2  18  29"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = [\n",
    "    {\"dep\": 5.5, \"step\": 1, \"a\": 20, \"b\": 30},\n",
    "    {\"dep\": 5.5, \"step\": 2, \"a\": 25, \"b\": 37},\n",
    "    {\"dep\": 6.1, \"step\": 1, \"a\": 22, \"b\": 19},\n",
    "    {\"dep\": 6.1, \"step\": 2, \"a\": 18, \"b\": 29},\n",
    "]\n",
    "\n",
    "\n",
    "df = pd.DataFrame(df)\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">a</th>\n",
       "      <th colspan=\"2\" halign=\"left\">b</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>step</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>dep</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>5.5</th>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6.1</th>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       a       b    \n",
       "step   1   2   1   2\n",
       "dep                 \n",
       "5.5   20  25  30  37\n",
       "6.1   22  18  19  29"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(index=\"dep\", names_from=\"step\", flatten_levels=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The order of the levels can be changed with the `levels_order` parameter, which internally uses pandas' [reorder_levels](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.reorder_levels.html):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th>step</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>b</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>dep</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>5.5</th>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6.1</th>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "step   1   2   1   2\n",
       "       a   a   b   b\n",
       "dep                 \n",
       "5.5   20  25  30  37\n",
       "6.1   22  18  19  29"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(\n",
    "    index=\"dep\", names_from=\"step\", flatten_levels=False, levels_order=[\"step\", None]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>a_1</th>\n",
       "      <th>a_2</th>\n",
       "      <th>b_1</th>\n",
       "      <th>b_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.1</td>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  a_1  a_2  b_1  b_2\n",
       "0  5.5   20   25   30   37\n",
       "1  6.1   22   18   19   29"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(\n",
    "    index=\"dep\",\n",
    "    names_from=\"step\",\n",
    "    flatten_levels=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>1_a</th>\n",
       "      <th>2_a</th>\n",
       "      <th>1_b</th>\n",
       "      <th>2_b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.1</td>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  1_a  2_a  1_b  2_b\n",
       "0  5.5   20   25   30   37\n",
       "1  6.1   22   18   19   29"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(\n",
    "    index=\"dep\", names_from=\"step\", flatten_levels=True, levels_order=[\"step\", None]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`names_sep` and `names_glue` come in handy in situations where `names_from` and/or `values_from` contain multiple variables; it is used primarily when the columns are flattened. The default value for `names_sep` is ``_``:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>a_1</th>\n",
       "      <th>a_2</th>\n",
       "      <th>b_1</th>\n",
       "      <th>b_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.1</td>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  a_1  a_2  b_1  b_2\n",
       "0  5.5   20   25   30   37\n",
       "1  6.1   22   18   19   29"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# default value of names_sep is '_'\n",
    "df.pivot_wider(index=\"dep\", names_from=\"step\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>a1</th>\n",
       "      <th>a2</th>\n",
       "      <th>b1</th>\n",
       "      <th>b2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.1</td>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  a1  a2  b1  b2\n",
       "0  5.5  20  25  30  37\n",
       "1  6.1  22  18  19  29"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(index=\"dep\", names_from=\"step\", names_sep=\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With `names_glue` you can glue the individual levels (if MultiIndex) into one (similar to `names_sep`), or you can modify the final columns, as long as it can be passed to `pd.Index.map`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>a_1</th>\n",
       "      <th>a_2</th>\n",
       "      <th>b_1</th>\n",
       "      <th>b_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.1</td>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  a_1  a_2  b_1  b_2\n",
       "0  5.5   20   25   30   37\n",
       "1  6.1   22   18   19   29"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# replicate `names_sep`\n",
    "df.pivot_wider(index=\"dep\", names_from=\"step\", names_sep=None, names_glue=\"_\".join)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dep</th>\n",
       "      <th>a_step1</th>\n",
       "      <th>a_step2</th>\n",
       "      <th>b_step1</th>\n",
       "      <th>b_step2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.5</td>\n",
       "      <td>20</td>\n",
       "      <td>25</td>\n",
       "      <td>30</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.1</td>\n",
       "      <td>22</td>\n",
       "      <td>18</td>\n",
       "      <td>19</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   dep  a_step1  a_step2  b_step1  b_step2\n",
       "0  5.5       20       25       30       37\n",
       "1  6.1       22       18       19       29"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# going beyond names_sep\n",
    "df.pivot_wider(\n",
    "    index=\"dep\",\n",
    "    names_from=\"step\",\n",
    "    names_sep=None,\n",
    "    names_glue=lambda col: f\"{col[0]}_step{col[1]}\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are scenarios where the column order of the final dataframe is important:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Salesman</th>\n",
       "      <th>Height</th>\n",
       "      <th>product</th>\n",
       "      <th>price</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Knut</td>\n",
       "      <td>6</td>\n",
       "      <td>bat</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Knut</td>\n",
       "      <td>6</td>\n",
       "      <td>ball</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Knut</td>\n",
       "      <td>6</td>\n",
       "      <td>wand</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Steve</td>\n",
       "      <td>5</td>\n",
       "      <td>pen</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Salesman  Height product  price\n",
       "0     Knut       6     bat      5\n",
       "1     Knut       6    ball      1\n",
       "2     Knut       6    wand      3\n",
       "3    Steve       5     pen      2"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = [\n",
    "    {\"Salesman\": \"Knut\", \"Height\": 6, \"product\": \"bat\", \"price\": 5},\n",
    "    {\"Salesman\": \"Knut\", \"Height\": 6, \"product\": \"ball\", \"price\": 1},\n",
    "    {\"Salesman\": \"Knut\", \"Height\": 6, \"product\": \"wand\", \"price\": 3},\n",
    "    {\"Salesman\": \"Steve\", \"Height\": 5, \"product\": \"pen\", \"price\": 2},\n",
    "]\n",
    "\n",
    "df = pd.DataFrame(df)\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Salesman</th>\n",
       "      <th>Height</th>\n",
       "      <th>product_1</th>\n",
       "      <th>product_2</th>\n",
       "      <th>product_3</th>\n",
       "      <th>price_1</th>\n",
       "      <th>price_2</th>\n",
       "      <th>price_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Knut</td>\n",
       "      <td>6</td>\n",
       "      <td>bat</td>\n",
       "      <td>ball</td>\n",
       "      <td>wand</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Steve</td>\n",
       "      <td>5</td>\n",
       "      <td>pen</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Salesman  Height product_1 product_2 product_3  price_1  price_2  price_3\n",
       "0     Knut       6       bat      ball      wand      5.0      1.0      3.0\n",
       "1    Steve       5       pen       NaN       NaN      2.0      NaN      NaN"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "idx = df.groupby([\"Salesman\", \"Height\"]).cumcount().add(1)\n",
    "\n",
    "(df.assign(idx=idx).pivot_wider(index=[\"Salesman\", \"Height\"], names_from=\"idx\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To get the columns in a form where `product` alternates with `price`, we can combine `pivot_wider` (or plain `pd.pivot`) with `pd.sort_index` and `janitor.collapse_levels`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Salesman</th>\n",
       "      <th>Height</th>\n",
       "      <th>product_1</th>\n",
       "      <th>price_1</th>\n",
       "      <th>product_2</th>\n",
       "      <th>price_2</th>\n",
       "      <th>product_3</th>\n",
       "      <th>price_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Knut</td>\n",
       "      <td>6</td>\n",
       "      <td>bat</td>\n",
       "      <td>5.0</td>\n",
       "      <td>ball</td>\n",
       "      <td>1.0</td>\n",
       "      <td>wand</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Steve</td>\n",
       "      <td>5</td>\n",
       "      <td>pen</td>\n",
       "      <td>2.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Salesman  Height product_1  price_1 product_2  price_2 product_3  price_3\n",
       "0     Knut       6       bat      5.0      ball      1.0      wand      3.0\n",
       "1    Steve       5       pen      2.0       NaN      NaN       NaN      NaN"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(\n",
    "    df.assign(idx=idx)\n",
    "    .pivot_wider(index=[\"Salesman\", \"Height\"], names_from=\"idx\", flatten_levels=False)\n",
    "    .sort_index(level=\"idx\", axis=\"columns\", sort_remaining=False)\n",
    "    .collapse_levels()\n",
    "    .reset_index()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>geoid</th>\n",
       "      <th>name</th>\n",
       "      <th>variable</th>\n",
       "      <th>estimate</th>\n",
       "      <th>error</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>pop_renter</td>\n",
       "      <td>1434765</td>\n",
       "      <td>16736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>median_rent</td>\n",
       "      <td>747</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>13</td>\n",
       "      <td>Georgia</td>\n",
       "      <td>pop_renter</td>\n",
       "      <td>3592422</td>\n",
       "      <td>33385</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>13</td>\n",
       "      <td>Georgia</td>\n",
       "      <td>median_rent</td>\n",
       "      <td>927</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   geoid     name     variable  estimate  error\n",
       "0      1  Alabama   pop_renter   1434765  16736\n",
       "1      1  Alabama  median_rent       747      3\n",
       "2     13  Georgia   pop_renter   3592422  33385\n",
       "3     13  Georgia  median_rent       927      3"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame(\n",
    "    {\n",
    "        \"geoid\": [1, 1, 13, 13],\n",
    "        \"name\": [\"Alabama\", \"Alabama\", \"Georgia\", \"Georgia\"],\n",
    "        \"variable\": [\n",
    "            \"pop_renter\",\n",
    "            \"median_rent\",\n",
    "            \"pop_renter\",\n",
    "            \"median_rent\",\n",
    "        ],\n",
    "        \"estimate\": [1434765, 747, 3592422, 927],\n",
    "        \"error\": [16736, 3, 33385, 3],\n",
    "    }\n",
    ")\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>geoid</th>\n",
       "      <th>name</th>\n",
       "      <th>median_rent_estimate</th>\n",
       "      <th>pop_renter_estimate</th>\n",
       "      <th>median_rent_error</th>\n",
       "      <th>pop_renter_error</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>747</td>\n",
       "      <td>1434765</td>\n",
       "      <td>3</td>\n",
       "      <td>16736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>13</td>\n",
       "      <td>Georgia</td>\n",
       "      <td>927</td>\n",
       "      <td>3592422</td>\n",
       "      <td>3</td>\n",
       "      <td>33385</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   geoid     name  median_rent_estimate  pop_renter_estimate  \\\n",
       "0      1  Alabama                   747              1434765   \n",
       "1     13  Georgia                   927              3592422   \n",
       "\n",
       "   median_rent_error  pop_renter_error  \n",
       "0                  3             16736  \n",
       "1                  3             33385  "
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.pivot_wider(\n",
    "    index=[\"geoid\", \"name\"],\n",
    "    names_from=\"variable\",\n",
    "    values_from=[\"estimate\", \"error\"],\n",
    "    levels_order=[\"variable\", None],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the reshaping above, we would like to maintain the order in `variable`, where `pop_renter` comes before `median_rent`; this can be achieved by converting the `variable` column to a categorical, before reshaping:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>geoid</th>\n",
       "      <th>name</th>\n",
       "      <th>pop_renter_estimate</th>\n",
       "      <th>median_rent_estimate</th>\n",
       "      <th>pop_renter_error</th>\n",
       "      <th>median_rent_error</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>1434765</td>\n",
       "      <td>747</td>\n",
       "      <td>16736</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>13</td>\n",
       "      <td>Georgia</td>\n",
       "      <td>3592422</td>\n",
       "      <td>927</td>\n",
       "      <td>33385</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   geoid     name  pop_renter_estimate  median_rent_estimate  \\\n",
       "0      1  Alabama              1434765                   747   \n",
       "1     13  Georgia              3592422                   927   \n",
       "\n",
       "   pop_renter_error  median_rent_error  \n",
       "0             16736                  3  \n",
       "1             33385                  3  "
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(\n",
    "    df.encode_categorical(variable=(None, \"appearance\")).pivot_wider(\n",
    "        index=[\"geoid\", \"name\"],\n",
    "        names_from=\"variable\",\n",
    "        values_from=[\"estimate\", \"error\"],\n",
    "        levels_order=[\"variable\", None],\n",
    "    )\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
  },
  "kernelspec": {
   "display_name": "Python 3.8.10 64-bit ('base': conda)",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
